/** * This is a small library for (mostly 2D) vector mathematics. * Internally, the vectors used by this library are simple arrays of numbers. * The functions provided by this library do not alter the input vectors, * treating each vector as an immutable object. */ var VecMath = (function() { /** * Adds two vectors. * @param {vec} a * @param {vec} b * @return {vec} */ var add = function(a, b) { var result = []; for(var i=0; i tolerance) { return false; } } else if(a[i] != b[i]) return false; } return true; }; /** * Returns the length of a vector. * @param {vec} vector * @return {number} */ var length = function(vector) { var length = 0; for(var i=0; i < vector.length; i++) { length += vector[i]*vector[i]; } return Math.sqrt(length); }; /** * Computes the normalization of a vector - its unit vector. * @param {vec} v * @return {vec} */ var normalize = function(v) { var vHat = []; var vLength = length(v); for(var i=0; i < v.length; i++) { vHat[i] = v[i]/vLength; } return vHat; }; /** * Computes the projection of vector b onto vector a. * @param {vec} a * @param {vec} b * @return {vec} */ var projection = function(a, b) { var scalar = scalarProjection(a, b); var aHat = normalize(a); return scale(aHat, scalar); }; /** * Computes the distance from a point to an infinitely stretching line. * Works for either 2D or 3D points. * @param {vec2 || vec3} pt * @param {vec2 || vec3} linePt1 A point on the line. * @param {vec2 || vec3} linePt2 Another point on the line. * @return {number} */ var ptLineDist = function(pt, linePt1, linePt2) { var a = vec(linePt1, linePt2); var b = vec(linePt1, pt); // Make 2D vectors 3D to compute the cross product. if(!a[2]) a[2] = 0; if(!b[2]) b[2] = 0; var aHat = normalize(a); var aHatCrossB = cross(aHat, b); return length(aHatCrossB); }; /** * Computes the distance from a point to a line segment. * Works for either 2D or 3D points. * @param {vec2 || vec3} pt * @param {vec2 || vec3} linePt1 The start point of the segment. * @param {vec2 || vec3} linePt2 The end point of the segment. * @return {number} */ var ptSegDist = function(pt, linePt1, linePt2) { var a = vec(linePt1, linePt2); var b = vec(linePt1, pt); var aDotb = dot(a,b); // Is pt behind linePt1? if(aDotb < 0) { return length(vec(pt, linePt1)); } // Is pt after linePt2? else if(aDotb > dot(a,a)) { return length(vec(pt, linePt2)); } // Pt must be between linePt1 and linePt2. else { return ptLineDist(pt, linePt1, linePt2); } }; /** * Computes the scalar projection of b onto a. * @param {vec2} a * @param {vec2} b * @return {vec2} */ var scalarProjection = function(a, b) { var aDotB = dot(a, b); var aLength = length(a); return aDotB/aLength; }; /** * Computes a scaled vector. * @param {vec2} v * @param {number} scalar * @return {vec2} */ var scale = function(v, scalar) { var result = []; for(var i=0; i